#include "FbxImporter.h"

namespace GC
{
	GC::FbxImporter::FbxImporter(const _TCHAR* a_inputName)
	{
		m_inputName = a_inputName;	
		//Set data to null to start with
		m_data = nullptr;
	}

	GC::FbxImporter::~FbxImporter()
	{		
	}

	const FbxData* GC::FbxImporter::GetData()
	{
		//If data isn't set or uninitialized
		if (m_data == nullptr || !m_data->IsInitialized() )
		{
			return nullptr;
		}
		
		return m_data.get();
	}

	const bool GC::FbxImporter::Import()
	{
		m_sdkManager = FbxManager::Create();
		FbxIOSettings* f_ios = FbxIOSettings::Create(m_sdkManager, IOSROOT );
		m_sdkManager->SetIOSettings(f_ios);

		m_scene = FbxScene::Create(m_sdkManager, "");

		#if defined (_DEBUG)
			Cout << _T("Started loading FBX scene") << std::endl;
		#endif

		//Try to load scene
		if (!TryToLoadScene() )
		{
			//If it failed destroy all the fbx pointers
			m_scene->Destroy();
			m_sdkManager->Destroy();
			return false;
		}

		#if defined (_DEBUG)
			Cout << _T("Finished loading FBX scene") << std::endl;
		#endif
		ConverterApp::LogMessage(L"Finished loading fbx scene. Starting to fetch scene data");	

		int f_animationStacksCount = m_scene->GetSrcObjectCount<FbxAnimStack>();

		if (f_animationStacksCount > 0)
		{
			FbxAnimStack* f_animationStack = m_scene->GetSrcObject<FbxAnimStack>(0);

			m_scene->GetEvaluator()->SetContext( f_animationStack);
			//firstAnim = false;   what is this for?
		}

		#if defined (_DEBUG)
			Cout << _T("Started Initilizing FbxData") << std::endl;
		#endif

		//Init FbxData
		if (!InitilizeFbxData() )
		{
			m_scene->Destroy();
			m_sdkManager->Destroy();
			return false;
		}

		#if defined (_DEBUG)
			Cout << _T("Finished Initializing FbxData") << std::endl;
		#endif

		#if defined (_DEBUG)
			ConverterApp::LogMessage(L"Setting Mesh, bone & skeleton data");
			Cout << _T("Setting Mesh, bone & skeleton data") << std::endl;
		#endif

		if (!m_data->HandleNodes( m_rootNode, m_rootNode ,m_sdkManager ) )
		{
			m_scene->Destroy();
			m_sdkManager->Destroy();
			return false;
		}

		#if defined (_DEBUG)
			ConverterApp::LogMessage(L"Setting Animation data");
			Cout << _T("Setting Animation data") << std::endl;
		#endif		

		m_data->HandleAnimations( m_scene, m_rootNode );

		//Clear the nodemap since the Fbx SDK nodes will be corrupt 
		FbxHelper::ClearNodeMap();
		//Done with importing, destroy the FBX SDK objects
		m_scene->Destroy();
		m_sdkManager->Destroy();

		return true;
	}
	
	//Attempts to load the FbxScene
	const bool GC::FbxImporter::TryToLoadScene()
	{
		fbxsdk_2014_1::FbxImporter* f_importer = fbxsdk_2014_1::FbxImporter::Create( m_sdkManager, "");

		char* f_importPath;
		//Copy m_inputName to f_importPath
		#if defined (_UNICODE)
			FbxWCToUTF8(m_inputName, f_importPath);
		#else
			_tcscpy_s(m_inputName, f_importPath);
		#endif

		bool f_status = f_importer->Initialize(f_importPath, -1, m_sdkManager->GetIOSettings() );

		if (!f_status)
		{
			ConverterApp::LogMessage(L"Failed: To initialize FBX importer.");
			return false;
		}
		//Import scene after initializing
		f_status = f_importer->Import(m_scene);
		//If it failed to import scene the file is password protected
		if (!f_status)
		{
			ConverterApp::LogMessage(L"Failed: The fbx file is password protected");
		}

		f_importer->Destroy();

		return f_status;
	}
	//Creates the FbxData object
	const bool GC::FbxImporter::InitilizeFbxData() 
	{	
		m_rootNode = m_scene->GetRootNode();		
		//Reserves space for total nodecount
		FbxHelper::ReserveNodeMap( m_scene->GetNodeCount() );

		m_data = std::make_shared<FbxData>( m_rootNode, m_scene);	
		
		return m_data->IsInitialized();
	}	
}